/*
 * AbstractGameEditorComponent.java
 *
 * Created on 14 de Julho de 2011, 17:58
 */

package intopo.game.gui;

import intopo.game.Game;
import intopo.game.Strategy;

import java.awt.Color;
import java.io.Serializable;
import javax.swing.UIManager;

/**
 * An abstract class that represents a swing form that allows editing the parameters of a game.
 *
 * <p> The description of a game must return a component that is used to show and edit the game parameters.  This class must implement two methods to get and set the game used by the component.  The same component instance may be used to display games with different parameters.
 *
 * <p> Implementors must also provide a method that returns a textual description of the game to be used in a configuration file.
 *
 * @author  pedro
 */
abstract public class AbstractGameEditorComponent<
		G extends Game<S>,
		S extends Strategy<S>>
	extends javax.swing.JPanel
	implements Serializable
{
	/**
	 * The game that is being edited and shown by this component.
	 */
	protected G game;
	/**
	 * Creates new form with no game.  If there are any components, they should show no values.
	 */
	protected AbstractGameEditorComponent ()
	{
		initComponents ();
	}
	/**
	 * Get a description of this game that can be written in a text configuration file.
	 * @return A description suitable for a text configuration file.
	 */
	abstract public String getConfigFileDescription ();
	/**
	 * Gets the game that is being edited and shown by this form.
	 */
	abstract public G getGame ();

	public void initC () {
		this.initComponents ();
	}
	/**
	 * Sets the game that is being edited and shown by this form.  Updates the components in this form.
	 * @param game The game that is being edited and shown by this form.
	 */
	abstract public void setGame (G game);
	/**
	 * Updates the colours of the text field component based on the given flag.
	 * @param textField The text field component to update.
	 * @param ok Ok flag.
	 */
	final protected void update (final javax.swing.JFormattedTextField textField, final boolean ok)
	{
		if (ok) {
			textField.setForeground (UIManager.getColor ("FormattedTextField.foreground"));
			textField.setBackground (UIManager.getColor ("FormattedTextField.background"));
		}
		else {
			textField.setForeground (Color.RED);
			textField.setBackground (Color.WHITE);
		}
	}
	final protected void updateInfoPanel (boolean isVisible)
	{
		this.infoPanel.setVisible (isVisible);
		if (isVisible) {
			try {
				Game g = this.getGame ();
				this.lowestPayoffFormattedTextField.setValue (g.lowestPayoff ());
				this.highestPayoffFormattedTextField.setValue (new Float (g.highestPayoff ()));
				this.paretoOptimalPayoffFormattedTextField.setValue (new Float (g.paretoPayoff ()));
			}
			catch (Exception e) {
				this.lowestPayoffFormattedTextField.setText ("");
				this.highestPayoffFormattedTextField.setText ("");
				this.paretoOptimalPayoffFormattedTextField.setText (e.getLocalizedMessage ());
			}
		}
	}
	/**
	 * Updates the components with the values of the game parameter.
	 * <p><b>Pre-condition</b> attribute {@code game} is non {@code null}.
	 */
	final protected void updateComponents ()
	{
		
	}
	/**
	 * Adds the given {@code GameListener} to this component.
	 * @param gl The listener interested in game editing events.
	 */
	final public void addGameListener (GameListener<G, S> gl)
	{
		this.listenerList.add (GameListener.class, gl);
	}
	/**
	 * Notifies the game editing listeners that the given parameter has been updated.
	 * @param parameterName The name of the parameter that was updated.
	 * @param oldValue The old value of the parameter.
	 * @param newValue The new value of the parameter.
	 */
	final protected void fireParameterUpdated (String parameterName, Object oldValue, Object newValue)
	{
		GameListener<G, S>[] gla = this.listenerList.getListeners (GameListener.class);
		GameEvent<G, S> ge = new GameEvent<G, S> (game, parameterName, oldValue, newValue);
		for (GameListener gl : gla) {
			gl.parameterUpdate (ge);
		}
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
   // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
   private void initComponents() {
      java.awt.GridBagConstraints gridBagConstraints;

      infoPanel = new javax.swing.JPanel();
      javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
      lowestPayoffFormattedTextField = new javax.swing.JFormattedTextField();
      highestPayoffFormattedTextField = new javax.swing.JFormattedTextField();
      javax.swing.JLabel jLabel2 = new javax.swing.JLabel();
      paretoOptimalPayoffFormattedTextField = new javax.swing.JFormattedTextField();

      infoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("information"));
      infoPanel.setLayout(new java.awt.GridBagLayout());

      jLabel1.setText("Payoff range: ");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
      infoPanel.add(jLabel1, gridBagConstraints);

      lowestPayoffFormattedTextField.setColumns(5);
      lowestPayoffFormattedTextField.setEditable(false);
      infoPanel.add(lowestPayoffFormattedTextField, new java.awt.GridBagConstraints());

      highestPayoffFormattedTextField.setColumns(5);
      highestPayoffFormattedTextField.setEditable(false);
      infoPanel.add(highestPayoffFormattedTextField, new java.awt.GridBagConstraints());

      jLabel2.setText("Pareto optimal payoff: ");
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridx = 0;
      gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
      infoPanel.add(jLabel2, gridBagConstraints);

      paretoOptimalPayoffFormattedTextField.setColumns(5);
      paretoOptimalPayoffFormattedTextField.setEditable(false);
      gridBagConstraints = new java.awt.GridBagConstraints();
      gridBagConstraints.gridx = 1;
      gridBagConstraints.gridwidth = 2;
      gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
      infoPanel.add(paretoOptimalPayoffFormattedTextField, gridBagConstraints);

      setLayout(new java.awt.BorderLayout());
   }// </editor-fold>//GEN-END:initComponents
	
	
   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JFormattedTextField highestPayoffFormattedTextField;
   protected javax.swing.JPanel infoPanel;
   private javax.swing.JFormattedTextField lowestPayoffFormattedTextField;
   private javax.swing.JFormattedTextField paretoOptimalPayoffFormattedTextField;
   // End of variables declaration//GEN-END:variables
}
